/**
 * 
 */
package org.vsg.stock.extension.processor;

import java.text.DecimalFormat;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vsg.common.exceptions.service.ServiceException;
import org.vsg.stock.basic.domain.StockDailyLine;
import org.vsg.stock.extension.vo.CalculatePatternStock;
import org.vsg.stock.extension.vo.CloserPatternStock;
import org.vsg.stock.extension.vo.HistoryPatternStock;

/**
 * @author Bill Vison
 *
 */
public class StandardFilterProcessorManager implements FilterProcessorManager {

	/**
	 * set the logger for develope code , do not use System.print(ln) to out print message.
	 */
	private static final Logger logger = LoggerFactory.getLogger(StandardFilterProcessorManager.class);	

	private DecimalFormat df = new DecimalFormat("##0.0000");	
	
	@Resource
	private List<PatternFilterProcessor> allPatternFilterProcessor;	
	
	private Map<String , Double> ratioWeight;

	public List<PatternFilterProcessor> getAllPatternFilterProcessor() {
		return allPatternFilterProcessor;
	}

	public void setAllPatternFilterProcessor(
			List<PatternFilterProcessor> allPatternFilterProcessor) {
		this.allPatternFilterProcessor = allPatternFilterProcessor;
	}

	public Map<String, Double> getRatioWeight() {
		return ratioWeight;
	}

	public void setRatioWeight(Map<String, Double> ratioWeight) {
		this.ratioWeight = ratioWeight;
	}



	/* (non-Javadoc)
	 * @see org.vsg.stock.custcomp.processor.FilterProcessorManager#filterHandler(java.util.Map)
	 */
	@Override
	public List<CloserPatternStock> filterHandler(
			Map<String, List<HistoryPatternStock>> histPatternStockMap, String stockCode , List<StockDailyLine> allDailyLine)
			throws ServiceException {
		// TODO Auto-generated method stub
		Set<String> keys = histPatternStockMap.keySet();
		String key = null;
		List<HistoryPatternStock> historyPatternStockList = null;
		PatternFilterProcessor processor = null;
		
		List<CalculatePatternStock> cpsList = new LinkedList<CalculatePatternStock>();
		Map<String , CalculatePatternStock> cpsMap = new HashMap<String,CalculatePatternStock>();
		
		for (Iterator<PatternFilterProcessor> proceIter = allPatternFilterProcessor.iterator() ; proceIter.hasNext();) {
			processor = proceIter.next();

			double rw = ratioWeight.get(processor.getClass().getName());
			
			// --- invoke the processor handle ---
			for (Iterator<String> keyIter= keys.iterator() ; keyIter.hasNext();) {
				key = keyIter.next();
				double value = processor.calculateCloseValue(allDailyLine, (List)new LinkedList(histPatternStockMap.get(key)).clone());
				
				if (value < 0.5) {
					// --- remove the key
					keyIter.remove();
					logger.debug("not fit " + key);
				} else {
					CalculatePatternStock cps = cpsMap.get(key);
					if (cps != null) {
						double cpsValue = cps.getValue() + Double.parseDouble( df.format( value * rw) );
						cps.setValue( cpsValue);
						if (!cpsList.contains(cps)) {
							cpsList.add(cps);
						}
					} else {
						// --- create CalculatePatternStock ---
						cps = new CalculatePatternStock();
						cps.setStockCode( key );
						cps.setValue( Double.parseDouble( df.format( value * rw) ) );
						cpsList.add( cps );
						cpsMap.put(key, cps);
					}
				}
			}
			
			// --- sort the value ---
			Collections.sort( cpsList , new CalculatePatternStockComparator());
			
		}
		
		
		List<CloserPatternStock> cloPatternStockList = new LinkedList<CloserPatternStock>();
		// --- covert the handle object ---
		CalculatePatternStock cps = null;
		for (Iterator<CalculatePatternStock> cpsIter = cpsList.iterator(); cpsIter.hasNext();) {
			cps = cpsIter.next();
			
			
			List<HistoryPatternStock> hpsl = histPatternStockMap.get( cps.getStockCode() ) ;
			if (hpsl != null && hpsl.size() > 0) {
				CloserPatternStock cpstock = new CloserPatternStock();
				cpstock.setCloser( cps.getValue() );
				cpstock.setStockCode( cps.getStockCode() );
				cpstock.setStartDate( hpsl.get(0).getStartDate() );
				cpstock.setEndDate( hpsl.get(hpsl.size()-1).getEndDate() );
				cpstock.setPatternAll( hpsl );
				cloPatternStockList.add( cpstock );
			}
			
			
			cpsIter.remove();
		}
		
		return cloPatternStockList;
	}

}
